package android.db;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Rusiru Boteju
 */
public class HashDB implements MethodsList {

//    Hashtable ht_st_st = new Hashtable<String, String>();
//    Hashtable ht_st_int = new Hashtable<String, Integer>();
    Hashtable<String, Object> ht_st_obj = null;//new Hashtable<String, Object>();
    InetAddress host;
    int port;

    /**
     * Creating the table instance with InetAddress host, int port,
     * String userneme and String pwd
     * @HashDB createInstance
     * @param name
     * @param host
     * @param port
     * @param username
     * @param pwd
     * @throws Exception
     */
    public Hashtable<String, Object> createInstance(String name, InetAddress host, int port, String username,
            String pwd) throws Exception {
        try {
            this.host = host;
            this.port = port;
            this.ht_st_obj = new Hashtable<String, Object>(1000);
            this.ht_st_obj.put("DB_NAME", name);
            NewHashDB.addToVector(new NewHashDB(name, pwd, username, host, port));
            return this.ht_st_obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Creating the table instance with InetAddress host and int port
     * @HashDB createInstance
     * @param name
     * @param host
     * @param port
     * @throws Exception
     */
    public Hashtable<String, Object> createInstance(String name, InetAddress host, int port) throws Exception {
        try {
            this.host = host;
            this.port = port;
            this.ht_st_obj = new Hashtable<String, Object>(1000);
            this.ht_st_obj.put("DB_NAME", name);
            NewHashDB.addToVector(new NewHashDB(name, "nill", "nill", host, port));
            return this.ht_st_obj;
        } catch (Exception e) {
            return null;
        }
    }

    public void quit() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void set(String key, String stringValue) throws Exception {
        if (this.ht_st_obj != null) {
            this.ht_st_obj.put(key, stringValue);
        } else {
            throw new Exception();
        }
    }

//    public void set(String key, Number numberValue) throws Exception {
//        if (this.ht_st_obj != null) {
//            Double.toString(numberValue);
//            this.ht_st_obj.put(key, numberValue);
//        } else {
//            throw new Exception();
//        }
//    }
    public String get(String key) throws Exception {
        if (this.ht_st_obj != null) {
            if (this.ht_st_obj.get(key) == null) {
                return "nill";
            } else {
                return (String) this.ht_st_obj.get(key);
            }
        } else {
            throw new Exception();
        }
    }

    public String getset(String key, String stringValue) throws Exception {
        if (this.ht_st_obj != null) {
            if (this.ht_st_obj.get(key) == null) {
                return "nill";
            } else {
                String s = (String) this.ht_st_obj.get(key);
                this.ht_st_obj.put(key, stringValue);
                return s;
            }
        } else {
            throw new Exception();
        }
    }

//    public Object getset(String key, Number numberValue) throws Exception {
//        throw new UnsupportedOperationException("Not supported yet.");
//    }
    public long incr(String key) throws Exception {
        if (this.ht_st_obj != null) {
            String s = (String) this.ht_st_obj.get(key);

            if (isParsableToInt(s)) {
                return (Long.parseLong(s) + 1);
            } else {
                this.ht_st_obj.put(key, "1");
                return 1;
            }
        } else {
            throw new Exception();
        }
    }

    public boolean isParsableToInt(String i) {
        try {
            Double.parseDouble(i);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }

    public long incrby(String key, int delta) throws Exception {
        if (this.ht_st_obj != null) {
            String s = (String) this.ht_st_obj.get(key);
            if (isParsableToInt(s)) {
                return (Long.parseLong(s) + delta);
            } else {
                this.ht_st_obj.put(key, "1");
                return 1;
            }
        } else {
            throw new Exception();
        }
    }

    public long decr(String key) throws Exception {
        if (this.ht_st_obj != null) {
            String s = (String) this.ht_st_obj.get(key);
            if (isParsableToInt(s)) {
                return (Long.parseLong(s) - 1);
            } else {
                this.ht_st_obj.put(key, "1");
                return 1;
            }
        } else {
            throw new Exception();
        }
    }

    public long decrby(String key, int delta) throws Exception {
        if (this.ht_st_obj != null) {
            String s = (String) this.ht_st_obj.get(key);
            if (isParsableToInt(s)) {
                return (Long.parseLong(s) - delta);
            } else {
                this.ht_st_obj.put(key, "1");
                return 1;
            }
        } else {
            throw new Exception();
        }
    }

    public boolean exists(String key) throws Exception {

        if (this.ht_st_obj != null) {
            return this.ht_st_obj.containsKey(key);
        } else {
            throw new Exception();
        }
    }

    public long del(String... keys) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean del(String key) throws Exception {
        if (this.ht_st_obj != null) {
            if (this.ht_st_obj.containsKey(key)) {
                this.ht_st_obj.remove(key);
                return true;
            } else {
                return false;
            }
        } else {
            throw new Exception();
        }
    }

    @SuppressWarnings("unchecked")
	public List<String> keys(String pattern) throws Exception {
        if (this.ht_st_obj != null) {
            Pattern pat = Pattern.compile(pattern);
            Matcher match = null;
            Enumeration e = this.ht_st_obj.keys();
            ArrayList<String> al = new ArrayList<String>();
            String ss = "";
            while (e.hasMoreElements()) {
                ss = (String) e.nextElement();
                match = pat.matcher(ss);
                if (match.matches()) {
                    al.add(ss);
                }
            }
            return al;
        } else {
            throw new Exception();
        }
    }

    @SuppressWarnings("unchecked")
	public List<String> keys() throws Exception {
        if (this.ht_st_obj != null) {
            Enumeration e = this.ht_st_obj.keys();
            ArrayList<String> al = new ArrayList<String>();
            while (e.hasMoreElements()) {
                al.add((String) e.nextElement());
            }
            return al;
        } else {
            throw new Exception();
        }
    }

    public boolean rename(String oldkey, String newkey) throws Exception {
        if (this.ht_st_obj != null) {
            if (oldkey.equals(newkey)) {
                return false;
            }
            if (this.ht_st_obj.containsKey(oldkey)) {
                Object o = this.ht_st_obj.remove(oldkey);
                this.ht_st_obj.put(newkey, o);
                return true;
            } else {
                return false;
            }
        } else {
            throw new Exception();
        }
    }

    public long dbsize() throws Exception {
        if (this.ht_st_obj != null) {
            return this.ht_st_obj.size();
        } else {
            throw new Exception();
        }
    }

    public HashDB flushdb() throws Exception {
        this.ht_st_obj.clear();
        return this;

    }

    public HashDB flushall() throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean move(String key, int dbIndex) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mergeDb(Hashtable ht) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
